package com.attendcollatesys.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.WriteTable;
import com.attendcollatesys.entity.vo.ATLeaveExtraDetailVO;
import com.attendcollatesys.entity.vo.OverTimeResultVo;
import com.attendcollatesys.entity.vo.excel.AbnormalAtteSheetHeadVo;
import com.attendcollatesys.ex.handler.ex.DataUnFindRunTimeException;
import com.attendcollatesys.mapper.ATDayDetailMapper;
import com.attendcollatesys.service.ATLeaveExtraDetailService;
import com.attendcollatesys.service.AtteResultsService;
import com.attendcollatesys.service.ExcelService;
import com.attendcollatesys.util.TimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class ExcelServiceImpl implements ExcelService {

    @Autowired
    private AtteResultsService atteResultsService;

    @Autowired
    private ATLeaveExtraDetailService atLeaveExtraDetailService;

    @Autowired
    private ATDayDetailMapper atDayDetailMapper;


    @Override
    public Boolean checkExcelExist(List<String> date, String rtxNumber) {
        return atDayDetailMapper.checkDataExist(date, rtxNumber) == date.size();
    }


    @Override
    public Boolean getExcelResult(List<String> date, String rtxNumber, HttpServletResponse response) {


        try(ExcelWriter excelWriter=EasyExcel.write(response.getOutputStream()).build()) {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            //防止中文乱码
            String fileName = URLEncoder.encode("考勤结果", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=" + fileName + ".xlsx");
            // excelWriter = EasyExcel.write(response.getOutputStream()).build();

            writeWorkOverExcel(date, rtxNumber, excelWriter);
            writeAtDayDetailsExcel(date, rtxNumber, excelWriter);
            writeAbnormalAtteExcel(date, rtxNumber, excelWriter);

            excelWriter.finish();

        } catch (IOException e) {
            throw new RuntimeException("文件传输失败");
        }

        return true;
    }



    /**
     * 执行加班的sheet写入
     * @param date yyyy-MM-dd
     */
    private void writeWorkOverExcel(List<String> date, String rtxNumber, ExcelWriter excelWriter){
        WriteSheet writeSheet = EasyExcel.writerSheet("加班").needHead(Boolean.FALSE).build();
        List<OverTimeResultVo> data = new ArrayList<>();
        for (String dateTemp : date) {
            List<OverTimeResultVo> overTimeResultVos = atteResultsService.buildOTResult(dateTemp, null, rtxNumber, null, null);
            if (null == overTimeResultVos) {
                break;
            }
            data.addAll(overTimeResultVos);
        }
        if (data.size() == 0) {
            throw new DataUnFindRunTimeException("所选择月份无数据");
        }
        WriteTable writeTable0 = EasyExcel.writerTable(0).head(OverTimeResultVo.class).needHead(true).build();
        excelWriter.write(data, writeSheet, writeTable0);




    }

    /**
     * 执行考勤异常的sheet写入
     * @param date yyyy-MM-dd
     */
    private void writeAbnormalAtteExcel(List<String> date, String rtxNumber, ExcelWriter excelWriter){
        WriteSheet writeSheet = EasyExcel.writerSheet("考勤异常").needHead(Boolean.FALSE).build();
        List<List<Object>> data = new ArrayList<>();
        for (String dateTemp : date) {
            HashMap<String, String> dataMap = new HashMap<>();
            dataMap.put("rtxnumber", rtxNumber);
            dataMap.put("currentMonth", dateTemp);
            ATLeaveExtraDetailVO atLeaveExtraDetailVO;
            try {
                 atLeaveExtraDetailVO = atLeaveExtraDetailService.selectAllAbnormal(dataMap);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("考勤异常sheet生成失败");
            }
            //组装数据

            for(Map<String,String> map:atLeaveExtraDetailVO.getAbnormalSheet()){
                List<Object> rowData = new ArrayList<>();
                rowData.add(map.get("grpGroup"));
                rowData.add(map.get("abName"));
                rowData.add(map.get("illustrate"));
                rowData.add(map.get("head"));
                data.add(rowData);
            }

        }
        WriteTable writeTable0 = EasyExcel.writerTable(0).head(AbnormalAtteSheetHeadVo.class).needHead(true).build();
        excelWriter.write(data, writeSheet, writeTable0);

    }

    /**
     * 执行考勤结果的sheet页写入
     * @param date yyyy-MM-dd

     */
    private void writeAtDayDetailsExcel(List<String> date, String rtxNumber, ExcelWriter excelWriter) {
        int index = 0;
        WriteSheet writeSheet = EasyExcel.writerSheet("考勤").needHead(Boolean.FALSE).build();
        for (String dateTemp : date) {
            int daysInMonth = TimeUtil.getDaysInMonth(dateTemp);
            String title = "中科软科技股份有限公司2023年核心系统开发费用结算单-" + dateTemp.substring(0, 4) + "年" + dateTemp.substring(5, 7) + "月外包人员考勤明细";
            List<List<String>> head = new ArrayList<>();
            //组装表头
            List<String> headerRow = new ArrayList<>();
            headerRow.add(title);
            headerRow.add("姓名/日期");
            head.add(headerRow);
            for (int i = 1; i <= daysInMonth; i++) {
                List<String> headerRow2 = new ArrayList<>();
                headerRow2.add(title);
                headerRow2.add(String.valueOf(i));
                head.add(headerRow2);
            }
            List<String> headerRowEnd = new ArrayList<>();
            headerRowEnd.add(title);
            headerRowEnd.add("出勤天数");
            head.add(headerRowEnd);
            //组装数据
            List<List<Object>> data = new ArrayList<>();
            List<Map<String, String>> dayAttResult = atteResultsService.getDayAttResult(dateTemp, null, rtxNumber);
            if(dayAttResult==null){
                continue;
            }
            for (Map<String, String> resuMap : dayAttResult) {
                List<Object> rowData = new ArrayList<>();
                rowData.add(resuMap.get("name"));
                for (int i = 1; i <= daysInMonth; i++) {
                    rowData.add(null == resuMap.get(String.valueOf(i)) ? "" : resuMap.get(String.valueOf(i)));
                }
                double attDays=resuMap.values()
                        .stream()
                        .mapToDouble(v -> {
                            if ("√".equals(v)) {
                                return 1.0;
                            } else if ("请假半天".equals(v)) {
                                return 0.5;
                            } else if ("缺勤半天".equals(v)) {
                                return 0.5;
                            } else if ("迟到".equals(v)) {
                                return 1.0;
                            } else {
                                return 0.0;
                            }
                        }).sum();
                rowData.add(attDays);
                data.add(rowData);
            }
            WriteTable writeTable0 = EasyExcel.writerTable(index).head(head).needHead(true).build();
            ArrayList<Object> temp = new ArrayList<>(2);
            for (int j = 0; j < 2; j++) {
                temp.add("");
            }
            excelWriter.write(data, writeSheet, writeTable0);
            //输出两个空白行
            excelWriter.write(temp, writeSheet);
            index++;
        }
    }


}
